<html>

<head>
<meta charset="utf-8">

<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>新建网页 1</title>
</head>

<body text="#FFFFFF" bgcolor="#000000">

<p>//NC1020闪存的分布与切换</p>
<p>&nbsp;<font size="2"> 这里我们先讨论NC1020闪存的基本情况.</font></p>
<p><font size="2">1.闪存的基本参数</font></p>
<p><font size="2">&nbsp; 闪存的类型: NOR FLASH</font></p>
<p><font size="2">&nbsp; 闪存的大小: 512KB</font></p>
<p><font size="2">&nbsp; 闪存块大小: 2K</font></p>
<p>　</p>
<p><font size="2">2.NC1020闪存的分布</font></p>
<p><font size="2">&nbsp;由于6502最大寻址空间是64K,但NC1020有512K的闪存区域,那么是这样分布的呢?</font></p>
<p><font size="2">很显然,NC1020采用了分页码的方法,可以这样说,一个班只能容纳64个人,现在要招收512个人</font></p>
<p><font size="2">显然,一个班是不够的,要有16个班,分别为00班,01 班,02 班......0F 班.</font></p>
<p><font size="2">&nbsp; NC1020的闪存也是这样分配的,分为 0F 个页码,每个页码32K</font></p>
<p><font size="2">&nbsp; 顺便说说NC1020存储器的分布:</font></p>
<p><font size="2">&nbsp; ①RAM的分布情况</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp; NC1020RAM的大小:24K</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp; 地址0000-地址3FFFF&nbsp; :&nbsp; 16K</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp; 00页码的 4000-5FFF(6000-7FFF)&nbsp;&nbsp; :&nbsp; 
8K</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp; 
这里要说明的是,00页码的4000-5FFF的内容是会随着地址6000-7FFF的内容的改变而改变</font></p>
<p><font size="2">例如 在NCTOOLS下&nbsp; E C 6000 00, 输入30, 然后 D 4000 00,发现也变为30了,<b>不过这在NC1020模拟器上是看不出来的.</b></font></p>
<p><font size="2"><b>因为模拟器和实际机型不一样.</b></font></p>
<p><font size="2"><b>&nbsp; </b>②闪存的分布</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp; 01-0F 页码的 4000-BFFF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
总计:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 32 * 15 = 480K</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp; 00 页码的8000-BFFF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
总计:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 32 / 2 = 16K</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp; <b>当地址0A的内容=00时的</b> 地址C000-DFFF&nbsp; 总计:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
16K</font></p>
<p><font size="2">&nbsp; 所以总的 闪存容量 = 480 + 16 + 16 = 512K</font></p>
<p>　</p>
<p><font size="2">3.闪存的切换</font></p>
<p><font size="2">&nbsp; 和CC800,PC1000等一样,是通过地址00来切换的.</font></p>
<p><font size="2">&nbsp; 切换闪存有2种情况:</font></p>
<p><font size="2">&nbsp; ●当前代码处于 随机存储器RAM范围中</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp; 这种情况,切换到不同的页码比较简单,请看下面的例子:</font></p>
<p><font size="2">&nbsp; 例:&nbsp; 当前处于RAM区域,现在要读取03页码的4000-40FF的内容送到地址3000-3FFF</font></p>
<p><font size="2">&nbsp; 分析:要读取03页码的4000-40FF的数据,我们必须要先切换页码到03,这样才能读取03页码的数据</font></p>
<p><font size="2">&nbsp; 程序如下: </font></p>
<p><font size="2">&nbsp; 说明: 在切换闪存前,保护原来的页码和几个重要的地址,还要保证地址0A的内容为负数,即地址0A的最高位为0</font></p>
<p><font size="2">为什么要这样做,对于该例,完全可以不这样做,因为代码本身在RAM区域,不需要保护当前页码,但对于代码在闪存</font></p>
<p><font size="2">的那种情况,就一定要这样做了.因为我们在执行完该段程序返回后,要继续执行原来页码的程序,但由于我们切换到</font></p>
<p><font size="2">了另一个页码,如果不在程序返回前,切换入原来的页码,程序就无法执行.</font></p>
<p><font size="2">&nbsp;&nbsp; 
我举个形象点的例子:现在有16间房子,某人住在第3间房子,他每天的工作是打扫第3间房子的卫生,但打扫卫生的工具</font></p>
<p><font size="2">却放在04间房子,所以他打扫卫生的步骤是这样的:</font></p>
<p><font size="2">&nbsp; ①先进入第4间房子,拿卫生工具&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;相当于程序中的切换页码</font></p>
<p><font size="2">&nbsp; ②回到原来自己的房子&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;返回原来的页码</font></p>
<p><font size="2">&nbsp; ③继续工作&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;继续执行原来页码的程序</font></p>
<p>　</p>
<p><font size="2">&nbsp; 所以大家可以明白,如果某人到第4间房间拿了工具,却不返回原来的房间,后果是什么?</font></p>
<p><font size="2">&nbsp; </font></p>
<p><font size="2">&nbsp; 2000:LDA $00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;地址00的内容送入堆栈,保护地址00的内容</font></p>
<p><font size="2">&nbsp; 2002:PHA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</font></p>
<p><font size="2">&nbsp; 2003:LDA $0A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;地址0A的内容送入堆栈,保护地址0A的内容</font></p>
<p><font size="2">&nbsp; 2005:PHA</font></p>
<p><font size="2">&nbsp; 2006:LDA $0D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;地址0D的内容送入堆栈,保护地址0D的内容</font></p>
<p><font size="2">&nbsp; 2008:PHA</font></p>
<p><font size="2">&nbsp; 2009:LDA $0A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;地址0A的内容送寄存器A</font></p>
<p><font size="2">&nbsp; 200B:AND #$7F&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;寄存器A的值和7F进行逻辑与运算,这里功能是将地址0A的最高位置0</font></p>
<p><font size="2">&nbsp; 200D:STA $0A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</font></p>
<p>　</p>
<p><font size="2">&nbsp; 200F:LDA #$03&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;将页码03送寄存器A</font></p>
<p><font size="2">&nbsp; 2011:STA $00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;03送地址00,这里就切换到了03页码</font></p>
<p><font size="2">&nbsp; </font></p>
<p><font size="2">&nbsp; 2013:LDX #$00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;开始数据的传输</font></p>
<p><font size="2">&nbsp; 2015:LDA $4000,X</font></p>
<p><font size="2">&nbsp; 2018:STA $3000,X</font></p>
<p><font size="2">&nbsp; 201B:INX </font></p>
<p><font size="2">&nbsp; 201C:BNE $2015</font></p>
<p>　</p>
<p><font size="2">&nbsp; 201E:PLA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;数据传输完毕,把最开始压入堆栈的内容弹出,这里注意弹出的顺序</font></p>
<p><font size="2">&nbsp; 201F:STA $0D</font></p>
<p><font size="2">&nbsp; 2021:PLA</font></p>
<p><font size="2">&nbsp; 2022:STA $0A</font></p>
<p><font size="2">&nbsp; 2024:PLA</font></p>
<p><font size="2">&nbsp; 2025:STA $00</font></p>
<p><font size="2">&nbsp; 2027:RTS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;先前保护的地址内容已经完全恢复,程序结束返回</font></p>
<p>　</p>
<p><font size="2">●当前代码处于 闪存区域内</font></p>
<p><font size="2">&nbsp; 这种情况比上面的麻烦些,切换闪存的程序不可以在闪存区域执行,因为本身程序已经处于某页码的闪存区域</font></p>
<p><font size="2">又怎么可以切换到另外的页码呢?就好象你已经处于第3间房子,你不出去,在第3间房子里怎么可以到达第4间房子呢</font></p>
<p><font size="2">大家可能注意到 &quot;出去&quot;这两个字,不错,我们要先出去,这里我们可以想切换闪存的程序发送到 RAM里,然后程序调用</font></p>
<p><font size="2">该RAM里的程序即可实现页码的切换.</font></p>
<p>　</p>
<p><font size="2">例: 处于闪存区域的页码的切换,当前页码为0F页码,现在要读取03页码的4000-40FF的内容送到地址3000-3FFF</font></p>
<p><font size="2">&nbsp; 送入RAM的切换闪存的代码从地址4000开始</font></p>
<p><font size="2">&nbsp; 但实际执行切换闪存,读取数据的主程序是从地址4030开始</font></p>
<p><font size="2">&nbsp; <b>在写下面的代码前,要确定发送到的RAM的首地址,否则就无法写代码!!</b></font></p>
<p><font size="2"><b>&nbsp; 这里我们确定将代码送地址1700开始的RAM区域</b></font></p>
<p><font size="2">&nbsp; 4000:LDA $00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;地址00的内容送入堆栈,保护地址00的内容</font></p>
<p><font size="2">&nbsp; 4002:PHA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</font></p>
<p><font size="2">&nbsp; 4003:LDA $0A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;地址0A的内容送入堆栈,保护地址0A的内容</font></p>
<p><font size="2">&nbsp; 4005:PHA</font></p>
<p><font size="2">&nbsp; 4006:LDA $0D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;地址0D的内容送入堆栈,保护地址0D的内容</font></p>
<p><font size="2">&nbsp; 4008:PHA</font></p>
<p><font size="2">&nbsp; 4009:LDA $0A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;地址0A的内容送寄存器A</font></p>
<p><font size="2">&nbsp; 400B:AND #$7F&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;寄存器A的值和7F进行逻辑与运算,这里功能是将地址0A的最高位置0</font></p>
<p><font size="2">&nbsp; 400D:STA $0A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</font></p>
<p>　</p>
<p><font size="2">&nbsp; 400F:LDA #$03&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;将页码03送寄存器A</font></p>
<p><font size="2">&nbsp; 4011:STA $00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;03送地址00,这里就切换到了03页码</font></p>
<p><font size="2">&nbsp; </font></p>
<p><font size="2">&nbsp; 4013:LDX #$00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;开始数据的传输</font></p>
<p><font size="2">&nbsp; 4015:LDA $4000,X</font></p>
<p><font size="2">&nbsp; 4018:STA $3000,X</font></p>
<p><font size="2">&nbsp; 401B:INX </font></p>
<p><font size="2">&nbsp; <b>401C:BNE $1715&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;注意,这里不是BNE $4015,因为代码是从RAM地址1700开始执行的,所以是 BNE $1715</b></font></p>
<p>　</p>
<p><font size="2">&nbsp; 401E:PLA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;数据传输完毕,把最开始压入堆栈的内容弹出,这里注意弹出的顺序</font></p>
<p><font size="2">&nbsp; 401F:STA $0D</font></p>
<p><font size="2">&nbsp; 4021:PLA</font></p>
<p><font size="2">&nbsp; 4022:STA $0A</font></p>
<p><font size="2">&nbsp; 4024:PLA</font></p>
<p><font size="2">&nbsp; 4025:STA $00</font></p>
<p><font size="2">&nbsp; 4027:RTS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;先前保护的地址内容已经完全恢复,程序结束返回</font></p>
<p>　</p>
<p><font size="2">&nbsp;然后就是主程序,这里从地址4030开始吧</font></p>
<p><font size="2">&nbsp;在写主程序前,要先计算出发送到RAM区域的程序代码的字节数,这里是 十六进制28个字节,即十进制的40个字节</font></p>
<p><font size="2">4030:LDX #$00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;将地址4000-4027的数据送地址1700-1727</font></p>
<p><font size="2">4032:LDA $4000,X</font></p>
<p><font size="2">4035:STA $1700,X</font></p>
<p><font size="2">4038:INX</font></p>
<p><font size="2">4039:CPX #$28</font></p>
<p><font size="2">403B:BNE $4032</font></p>
<p>　</p>
<p><font size="2">403D:JSR $1700&nbsp;&nbsp;&nbsp; ;执行地址1700开始的程序</font></p>
<p><font size="2">4040:RTS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
;结束</font></p>

</body>

</html>